package com.ityuwen.mengyagushi.account.util;

import com.ityuwen.mengyagushi.account.mapper.UserAccountDetailMapper;
import com.ityuwen.mengyagushi.account.mapper.UserAccountMapper;
import com.ityuwen.mengyagushi.common.constant.RedisConstant;
import com.ityuwen.mengyagushi.common.constant.SystemConstant;
import com.ityuwen.mengyagushi.model.account.UserAccountDetail;
import com.ityuwen.mengyagushi.vo.account.AccountLockResultVo;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;

import java.util.concurrent.DelayQueue;
import java.util.concurrent.Delayed;
import java.util.concurrent.TimeUnit;

public class DelayTask implements Delayed {

	private RedisTemplate redisTemplate;

	private UserAccountMapper userAccountMapper;

	@Autowired
	private UserAccountDetailMapper detailMapper;

	public long timeout;

	public static final DelayQueue<DelayTask> DELAY_QUEUE = new DelayQueue<>();

	public DelayTask(RedisTemplate redisTemplate, UserAccountMapper userAccountMapper, UserAccountDetailMapper detailMapper) {
		this.redisTemplate = redisTemplate;
		this.userAccountMapper = userAccountMapper;
		this.detailMapper = detailMapper;
	}

	/**
	 * 自旋调用该方法，如果该方法的返回值小于等于0，该元素才会从延时队列中出队
	 * @param unit the time unit
	 * @return
	 */
	@Override
	public long getDelay(TimeUnit unit) {
		return this.timeout - System.currentTimeMillis();
	}

	/**
	 * 排队的方法
	 * @param o the object to be compared.
	 * @return
	 */
	@Override
	public int compareTo(Delayed o) {
		return (int)(this.timeout - ((DelayTask)o).timeout);
	}

	public void sendDelayMsg(String tradeNo, int delay, TimeUnit unit){
		this.timeout = System.currentTimeMillis() + unit.toMillis(delay);
		DELAY_QUEUE.put(this);
		// 最好使用线程池
		new Thread(() -> {
			try {
				DELAY_QUEUE.take();
				// 根据tradeNo获取redis中锁定缓存，解锁余额
				String key = RedisConstant.ACCOUNT_LOCK_PREFIX + tradeNo;
				AccountLockResultVo resultVo = (AccountLockResultVo)this.redisTemplate.opsForValue().get(key);
				if (resultVo == null) {
					return;
				}
				// 解锁余额
				if (this.userAccountMapper.unlock(resultVo.getUserId(), resultVo.getAmount()) == 1) {
					// 记录账户变化明细
					UserAccountDetail accountDetail = new UserAccountDetail();
					BeanUtils.copyProperties(resultVo, accountDetail);
					accountDetail.setTitle("解锁余额：" + resultVo.getContent());
					accountDetail.setTradeType(SystemConstant.ACCOUNT_TRADE_TYPE_UNLOCK);
					accountDetail.setOrderNo(tradeNo);
					this.detailMapper.insert(accountDetail);

					// 删除redis中的锁定信息缓存
					this.redisTemplate.delete(key);
				}
			} catch (InterruptedException e) {
				throw new RuntimeException(e);
			}
		}, "").start();
	}
}